package com.cqupt.utils;


import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.google.gson.Gson;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class MachineTranslationUtil {
    private static final String requestUrl = "https://itrans.xf-yun.com/v1/its";
    private static final String APPID = "a830a3cb";
    private static final String APISecret = "OWQzNmFkN2U3NmFmMjE5NTAyOTU4MTNl";
    private static final String APIKey = "6a73cfa8e86bde2f546004fcdff19224";
    private static final String RES_ID = "its_en_cn_word";
    private static final String FROM = "en";
    private static final String TO = "cn";
    private static final Gson gson = new Gson();

    public static String translate(String text) throws Exception {
        long startTime = System.currentTimeMillis();
        try {
            String resp = doRequest(text);
            System.out.println("resp=>" + resp);
            JsonParse myJsonParse = gson.fromJson(resp, JsonParse.class);
            String textBase64Decode = new String(Base64.getDecoder().decode(myJsonParse.payload.result.text), "UTF-8");
            JSONObject jsonObject = JSON.parseObject(textBase64Decode);
            System.out.println("text字段Base64解码后=>" + jsonObject);

            return jsonObject.getJSONObject("trans_result").getString("dst");
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            long endTime = System.currentTimeMillis();
            System.out.println("本次调用耗时: " + (endTime - startTime) + " ms");
        }
    }

    private static String doRequest(String text) throws Exception {
        URL realUrl = new URL(buildRequetUrl());
        URLConnection connection = realUrl.openConnection();
        HttpURLConnection httpURLConnection = (HttpURLConnection) connection;
        httpURLConnection.setDoInput(true);
        httpURLConnection.setDoOutput(true);
        httpURLConnection.setRequestMethod("POST");
        httpURLConnection.setRequestProperty("Content-type", "application/json");
        OutputStream out = httpURLConnection.getOutputStream();
        String params = buildParam(text);
        System.out.println("params=>" + params.replaceAll(" ", ""));
        out.write(params.getBytes());
        out.flush();
        InputStream is = null;
        try {
            is = httpURLConnection.getInputStream();
        } catch (Exception e) {
            is = httpURLConnection.getErrorStream();
            throw new Exception("make request error:" + "code is " + httpURLConnection.getResponseMessage() + readAllBytes(is));
        }
        return readAllBytes(is);
    }

    private static String buildRequetUrl() {
        URL url = null;
        String httpRequestUrl = requestUrl.replace("ws://", "http://").replace("wss://", "https://");
        try {
            url = new URL(httpRequestUrl);
            SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
            format.setTimeZone(TimeZone.getTimeZone("GMT"));
            String date = format.format(new Date());
            String host = url.getHost();
            StringBuilder builder = new StringBuilder("host: ").append(host).append("\n").append("date: ").append(date).append("\n").append("POST ").append(url.getPath()).append(" HTTP/1.1");
            Charset charset = Charset.forName("UTF-8");
            Mac mac = Mac.getInstance("hmacsha256");
            SecretKeySpec spec = new SecretKeySpec(APISecret.getBytes(charset), "hmacsha256");
            mac.init(spec);
            byte[] hexDigits = mac.doFinal(builder.toString().getBytes(charset));
            String sha = Base64.getEncoder().encodeToString(hexDigits);
            String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", APIKey, "hmac-sha256", "host date request-line", sha);
            String authBase = Base64.getEncoder().encodeToString(authorization.getBytes(charset));
            return String.format("%s?authorization=%s&host=%s&date=%s", requestUrl, URLEncoder.encode(authBase), URLEncoder.encode(host), URLEncoder.encode(date));
        } catch (Exception e) {
            throw new RuntimeException("assemble requestUrl error:" + e.getMessage());
        }
    }

    private static String buildParam(String text) {
        String param = "{" +
                "    \"header\": {" +
                "        \"app_id\": \"" + APPID + "\"," +
                "        \"status\": 3," +
                "        \"res_id\": \"" + RES_ID + "\"" +
                "    }," +
                "    \"parameter\": {" +
                "        \"its\": {" +
                "            \"from\": \"" + FROM + "\"," +
                "            \"to\": \"" + TO + "\"," +
                "            \"result\": {}" +
                "        }" +
                "    }," +
                "    \"payload\": {" +
                "        \"input_data\": {" +
                "            \"encoding\": \"utf8\"," +
                "            \"status\": 3," +
                "            \"text\": \"" + Base64.getEncoder().encodeToString(text.getBytes(StandardCharsets.UTF_8)) + "\"" +
                "        }" +
                "    }" +
                "}";
        return param;
    }

    private static String readAllBytes(InputStream is) throws IOException {
        byte[] b = new byte[1024];
        StringBuilder sb = new StringBuilder();
        int len = 0;
        while ((len = is.read(b)) != -1) {
            sb.append(new String(b, 0, len, "utf-8"));
        }
        return sb.toString();
    }

    class JsonParse {
        Payload payload;
    }

    class Payload {
        Result result;
    }

    class Result {
        String text;
    }
}
